package chapter8.eg7;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.embedded.EmbeddedChannel;
import org.junit.Before;
import org.junit.Test;

public class FixedLengthFrameDecoderTest {
  private ByteBuf buf;

  @Before
  public void before() {
    buf = Unpooled.buffer();
    for (int i = 0; i < 9; i++) {
      buf.writeByte(i);
    }
  }

  @Test
  public void testFrameDecoded() {
    ByteBuf input = buf.duplicate();
    EmbeddedChannel channel = new EmbeddedChannel(new FixedLengthFrameDecoder(3));
    assertTrue(channel.writeInbound(input.retain()));
    assertTrue(channel.finish());

    ByteBuf read = channel.readInbound();
    assertEquals(buf.readSlice(3), read);
    read.release();

    read = channel.readInbound();
    assertEquals(buf.readSlice(3), read);
    read.release();

    read = channel.readInbound();
    assertEquals(buf.readSlice(3), read);
    read.release();

    assertNull(channel.readInbound());
    buf.release();
  }

  @Test
  public void testFrameDecoded2() {
    ByteBuf input = buf.duplicate();
    EmbeddedChannel channel = new EmbeddedChannel(new FixedLengthFrameDecoder(3));
    assertFalse(channel.writeInbound(input.readBytes(2)));
    assertTrue(channel.writeInbound(input.readBytes(7)));
    assertTrue(channel.finish());

    ByteBuf read = channel.readInbound();
    assertEquals(buf.readSlice(3), read);
    read.release();

    read = channel.readInbound();
    assertEquals(buf.readSlice(3), read);
    read.release();

    read = channel.readInbound();
    assertEquals(buf.readSlice(3), read);
    read.release();

    assertNull(channel.readInbound());
    buf.release();
  }

}
